From b5f23288f7cedd188c7818b5ccdd6915ff2c343e Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 2 Mar 2015 19:17:25 -0800 Subject: [PATCH] Fix dep_targets for tests depending on libraries Before this commit the `dep_targets` function of `Context` didn't actually return all dependencies in the sense that unit tests (and likely examples) would not have the same package's library listed as a dependency. This commit rectifies the situation by ensuring that the package's library is included whenever necessary in the dependency list. Closes #1289 --- src/cargo/ops/cargo_rustc/context.rs | 21 +++++++++++++++++++-- src/cargo/ops/cargo_rustc/mod.rs | 11 ----------- tests/test_cargo_freshness.rs | 28 ++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/src/cargo/ops/cargo_rustc/context.rs b/src/cargo/ops/cargo_rustc/context.rs index e297ba405..409d1f761 100644 --- a/src/cargo/ops/cargo_rustc/context.rs +++ b/src/cargo/ops/cargo_rustc/context.rs @@ -284,7 +284,7 @@ impl<'a, 'b: 'a> Context<'a, 'b> { None => return vec!(), Some(deps) => deps, }; - deps.map(|id| self.get_package(id)).filter(|dep| { + let mut ret = deps.map(|id| self.get_package(id)).filter(|dep| { let pkg_dep = pkg.dependencies().iter().find(|d| { d.name() == dep.name() }).unwrap(); @@ -305,7 +305,24 @@ impl<'a, 'b: 'a> Context<'a, 'b> { }).filter_map(|pkg| { pkg.targets().iter().find(|&t| self.is_relevant_target(t)) .map(|t| (pkg, t)) - }).collect() + }).collect::>(); + + // If this target is a binary, test, example, etc, then it depends on + // the library of the same package. The call to `resolve.deps` above + // didn't include `pkg` in the return values, so we need to special case + // it here and see if we need to push `(pkg, pkg_lib_target)`. + if !target.profile().is_custom_build() && + (target.is_bin() || target.is_example()) { + let pkg = self.get_package(pkg.package_id()); + let target = pkg.targets().iter().filter(|t| { + t.is_lib() && t.profile().is_compile() && + (t.is_rlib() || t.is_dylib()) + }).next(); + if let Some(t) = target { + ret.push((pkg, t)); + } + } + return ret; } /// Gets a package for the given package id. diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index 569fa6781..3d875ba7f 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -678,17 +678,6 @@ fn build_deps_args(cmd: &mut CommandPrototype, target: &Target, try!(link_to(cmd, pkg, target, cx, kind)); } - let targets = package.targets().iter().filter(|target| { - target.is_lib() && target.profile().is_compile() - }); - - if (target.is_bin() || target.is_example()) && - !target.profile().is_custom_build() { - for target in targets.filter(|f| f.is_rlib() || f.is_dylib()) { - try!(link_to(cmd, package, target, cx, kind)); - } - } - return Ok(()); fn link_to(cmd: &mut CommandPrototype, pkg: &Package, target: &Target, diff --git a/tests/test_cargo_freshness.rs b/tests/test_cargo_freshness.rs index 394541be3..24fce3aa4 100644 --- a/tests/test_cargo_freshness.rs +++ b/tests/test_cargo_freshness.rs @@ -173,3 +173,31 @@ test!(changing_features_is_ok { execs().with_status(0) .with_stdout("")); }); + +test!(rebuild_tests_if_lib_changes { + let p = project("foo") + .file("Cargo.toml", r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + "#) + .file("src/lib.rs", "pub fn foo() {}") + .file("tests/foo.rs", r#" + extern crate foo; + #[test] + fn test() { foo::foo(); } + "#); + + assert_that(p.cargo_process("build"), + execs().with_status(0)); + assert_that(p.cargo("test"), + execs().with_status(0)); + + File::create(&p.root().join("src/lib.rs")).unwrap(); + + assert_that(p.cargo("build"), + execs().with_status(0)); + assert_that(p.cargo("test").arg("-v"), + execs().with_status(101)); +}); -- 2.30.2